package cn.core.data.service;

import cn.core.data.eo.DbTable;
import cn.core.data.eo.DbTableField;
import cn.core.data.mapper.DbTableFieldMapper;
import cn.core.data.mapper.DbTableMapper;
import cn.core.data.qo.DbTableFieldQO;
import cn.core.data.qo.DbTableQO;
import cn.core.data.vo.DbTableVO;
import cn.core.tool.exception.CoreException;
import cn.core.tool.util.CoreTool;
import cn.core.tool.util.Paging;
import cn.core.tool.util.Param;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;

/**
 * 数据库表 服务
 */
@Log4j2
@Service
public class DbTableService {

  @Resource
  private DbTableMapper dbTableMapper;

  @Resource
  private DbTableFieldMapper dbTableFieldMapper;

  /**
   * 数据库表 >>> 保存
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public DbTableVO save(DbTableVO eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (CoreTool.isEmpty(eo.getDbTableFieldList())) {
        throw new CoreException("字段列表为空！");
      }
      eo.setId(CoreTool.getUUID32());
      DbTable dbTable = new DbTable();
      BeanUtils.copyProperties(eo, dbTable);
      long weightOrder = 1l;
      for (DbTableField eDbTableField : eo.getDbTableFieldList()) {
        eDbTableField.setId(CoreTool.getUUID32());
        eDbTableField.setFkid(dbTable.getId());
        eDbTableField.setWeightOrder(weightOrder);
        weightOrder++;
      }
      dbTableMapper.saveDbTable(dbTable);
      dbTableFieldMapper.saveBatchDbTableField(new Paging<>(), eo.getDbTableFieldList());
      return eo;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 批量保存
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public Collection<DbTable> saveBatch(Collection<DbTable> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (DbTable eo : eos) {
        if (CoreTool.isNullEo(eo)) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
        eo.setId(CoreTool.getUUID32());
      }
      dbTableMapper.saveBatchDbTable(new Paging<>(), eos);
      return eos;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 修改
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public DbTableVO update(DbTableVO eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (CoreTool.isEmpty(eo.getDbTableFieldList())) {
        throw new CoreException("字段列表为空！");
      }
      DbTable oeo = dbTableMapper.pk(new DbTableQO().setId(eo.getId()));
      if (CoreTool.isNullEo(oeo)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
//      if (eo.getVersions() != null ? !eo.getVersions().equals(oeo.getVersions()) : oeo.getVersions() != null ? true : false) {
//        throw new CoreException(CoreException.E_VERSIONS_ERR);
//      }
      DbTable dbTable = new DbTable();
      BeanUtils.copyProperties(eo, dbTable);
      long weightOrder = 1l;
      for (DbTableField eDbTableField : eo.getDbTableFieldList()) {
        eDbTableField.setId(CoreTool.getUUID32());
        eDbTableField.setFkid(dbTable.getId());
        eDbTableField.setWeightOrder(weightOrder);
        weightOrder++;
      }
      dbTableMapper.updateDbTable(dbTable);
      dbTableFieldMapper.removeQuery(new DbTableFieldQO().setFkid(dbTable.getId()));
      dbTableFieldMapper.saveBatchDbTableField(new Paging<>(), eo.getDbTableFieldList());
      return eo;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 批量修改
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public Collection<DbTable> updateBatch(Collection<DbTable> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (DbTable eo : eos) {
        if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
        DbTable oeo = dbTableMapper.pk(new DbTableQO().setId(eo.getId()));
        if (CoreTool.isNullEo(oeo)) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
//        if (eo.getVersions() != null ? !eo.getVersions().equals(oeo.getVersions()) : oeo.getVersions() != null ? true : false) {
//          throw new CoreException(CoreException.E_VERSIONS_ERR);
//        }
      }
      dbTableMapper.updateBatchDbTable(new Paging<>(), eos);
      return eos;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 删除
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public void remove(DbTable eo) throws Exception {
    try {
      if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      dbTableMapper.removeDbTable(eo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 批量删除
   */
  @Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
  public void removeBatch(Collection<DbTable> eos) throws Exception {
    try {
      if (CoreTool.isEmpty(eos)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      for (DbTable eo : eos) {
        if (CoreTool.isNullEo(eo) || CoreTool.isNullStr(eo.getId())) {
          throw new CoreException(CoreException.E_PARAM_ERR);
        }
      }
      dbTableMapper.removeBatchDbTable(eos);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 数据量
   */
  public Long count(DbTableQO qo) throws Exception {
    try {
      return dbTableMapper.count(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 主键查询
   */
  public DbTable pk(DbTableQO qo) throws Exception {
    try {
      if (CoreTool.isNullEo(qo) || CoreTool.isNullStr(qo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      return dbTableMapper.pk(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 查询
   */
  public Collection<DbTable> query(DbTableQO qo) throws Exception {
    try {
      return dbTableMapper.query(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 分页
   */
  public Paging<DbTable> paging(Param<DbTableQO> param) throws Exception {
    try {
      if (CoreTool.isNullEo(param)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (param.getPage() < 1 || param.getRows() < 1) {
        throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
      }
      Paging<DbTable> paging = new Paging<>(param);
      if (CoreTool.isEmpty(param.getData()) || CoreTool.isNullEo(param.get())) {
        Long count = dbTableMapper.count(null);
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(dbTableMapper.paging(paging, null));
        }
      } else {
        Long count = dbTableMapper.count(param.get());
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(dbTableMapper.paging(paging, param.get()));
        }
      }
      return paging;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 业务数据量
   */
  public Long countVo(DbTableQO qo) throws Exception {
    try {
      return dbTableMapper.countVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 业务主键查询
   */
  public DbTableVO pkVo(DbTableQO qo) throws Exception {
    try {
      if (CoreTool.isNullEo(qo) || CoreTool.isNullStr(qo.getId())) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      return dbTableMapper.pkVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 业务查询
   */
  public Collection<DbTableVO> queryVo(DbTableQO qo) throws Exception {
    try {
      return dbTableMapper.queryVo(qo);
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 数据库表 >>> 业务分页
   */
  public Paging<DbTableVO> pagingVo(Param<DbTableQO> param) throws Exception {
    try {
      if (CoreTool.isNullEo(param)) {
        throw new CoreException(CoreException.E_PARAM_ERR);
      }
      if (param.getPage() < 1 || param.getRows() < 1) {
        throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
      }
      Paging<DbTableVO> paging = new Paging<>(param);
      if (CoreTool.isEmpty(param.getData()) || CoreTool.isNullEo(param.get())) {
        Long count = dbTableMapper.countVo(null);
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(dbTableMapper.pagingVo(paging, null));
        }
      } else {
        Long count = dbTableMapper.countVo(param.get());
        paging.setCount(count);
        if (count > 0) {
          if (count <= paging.getOffset()) {
            throw new CoreException(CoreException.E_PAGING_PARAM_ERR);
          }
          paging.setData(dbTableMapper.pagingVo(paging, param.get()));
        }
      }
      return paging;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

}
